﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using NSpeex;

    public class SpeexCodec
    {
        private object decoderSync;
        private object encoderSync;
        protected readonly SpeexEncoder _SpeexEncoder = new SpeexEncoder(BandMode.Narrow);
        protected readonly SpeexDecoder _SpeexDecoder = new SpeexDecoder(BandMode.Narrow, true);

        public SpeexCodec()
        {
            this._SpeexEncoder.Quality = 5;

            this.encoderSync = new object();
            this.decoderSync = new object();
        }

        public byte[] Decode(byte[] data)
        {
            lock (this.decoderSync)
            {
                try
                {
                    short[] outData = new short[this._SpeexDecoder.FrameSize * 2];
                    short[] destinationArray = new short[this._SpeexDecoder.Decode(data, 0, data.Length, outData, 0, false)];
                    Array.Copy(outData, 0, destinationArray, 0, destinationArray.Length);
                    return destinationArray.ToByteArray();
                }
                catch (Exception)
                {
                }
                return null;
            }
        }
        public byte[] Encode(byte[] data)
        {
            lock (this.encoderSync)
            {
                try
                {
                    short[] inData = data.ToShortArray();
                    byte[] outData = new byte[data.Length];
                    int length = this._SpeexEncoder.Encode(inData, 0, inData.Length, outData, 0, data.Length);
                    if (length != 0)
                    {
                        byte[] destinationArray = new byte[length];
                        Array.Copy(outData, destinationArray, length);
                        return destinationArray;
                    }
                }
                catch (Exception)
                {
                }
                return null;
            }
        }

    }

    internal static class Converters
    {
        public static byte[] ToByteArray(this short[] array)
        {
            byte[] dst = new byte[array.Length * 2];
            Buffer.BlockCopy(array, 0, dst, 0, dst.Length);
            return dst;
        }

        public static short[] ToShortArray(this byte[] array)
        {
            short[] dst = new short[array.Length / 2];
            Buffer.BlockCopy(array, 0, dst, 0, array.Length);
            return dst;
        }
    }

